package com.unitd.configclient.spring;

import com.unitd.configclient.ConfigcenterContext;
import com.unitd.frame.spring.SpringInstanceFactory;
import com.unitd.frame.spring.SpringInstanceProvider;
import com.unitd.frame.spring.prop.ResourceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.Properties;

/**
 * @desc 应用对应的属性配置信息加载配置类
 * 此类用于从配置中心服务端获取当前应用所属的属性配置信息,并将获取的属性配置信息用于当前应用服务
 * @filename ConfigCenterPropertyPlaceholderConfigurer.java
 * @copyright www.pactera.com.cn
 * @author Hudan
 * @version 1.0
 * @date 2018/1/13
 */
public class ConfigCenterPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer implements DisposableBean, ApplicationContextAware {

	private final static Logger logger = LoggerFactory.getLogger(ConfigCenterPropertyPlaceholderConfigurer.class);

	private ConfigcenterContext ccContext = ConfigcenterContext.getInstance();

	/**
	 * @desc 是否启用配置中心,默认:true
	 * @param remoteEnabled
	 */
	public void setRemoteEnabled(boolean remoteEnabled) {
		ccContext.setRemoteEnabled(remoteEnabled);
	}

	@Override
	protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)
			throws BeansException {
		super.processProperties(beanFactoryToProcess, props);
	}

	/**
	 * @desc 合并配置中心服务端的属性配置信息到当前服务
	 * @return Properties
	 */
	@Override
	protected Properties mergeProperties() throws IOException {
		logger.info("合并配置中心服务端的属性配置信息到当前服务!");
		Properties properties = super.mergeProperties();

		URL resource = Thread.currentThread().getContextClassLoader().getResource("confcenter.properties");
		Properties config;
		if (resource != null) {
			config = new Properties();
			config.load(new FileReader(new File(resource.getPath())));
			ResourceUtils.merge(properties);
			ResourceUtils.merge(config);

			//  初始化方法, 获取当前配置中心客户端应用的属性配置信息
			ccContext.init(false);
			// 合并远程属性配置信息到本地
			ccContext.mergeRemoteProperties(properties);
			// 启动服务的时候, 从配置中心服务端获取初始配置信息
			ccContext.syncConfigToServer(properties, true);
			return properties;
		} else {
			// 没有配置中心,则从服务本地取
			config = ResourceUtils.getAllProperties("unitd.configcenter");
			return config;
		}
	}

	/**
	 * @desc 继承Spring的DisposableBean类的destroy方法,每次调用完成后,都会去自动调用此方法,销毁当前应用上下文对象信息
	 */
	@Override
	public void destroy() {
		ccContext.close();
	}

	/**
	 * @desc 实现ApplicationContextAware接口, 重写设置Spring上下文对象
	 * @param applicationContext Spring上下文对象
	 */
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		if (SpringInstanceFactory.getSpringInstanceProvider() == null) {
			SpringInstanceFactory.setSpringInstanceProvider(new SpringInstanceProvider(applicationContext));
		}
	}
}